-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: add validate argument to merge #16275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
pandas/tests/reshape/test_merge.py
Outdated
right_w_dups = right.append(pd.DataFrame({'a':['e'], 'c':['moo']}, index=4)) | ||
merge(left, right_w_dups, left_index=True, right_index=True, validate='one_to_many') | ||
|
||
def f(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the with syntax
with pytest.raises(..):
...
doc/source/whatsnew/v0.21.0.txt
Outdated
.. _whatsnew_0210.enhancements.merge_validate: | ||
|
||
``merge`` supports ``validate`` argument to test merge | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a bit verbose
pandas/core/reshape/merge.py
Outdated
|
||
|
||
if self.validate == "one_to_one" or self.validate == "1:1": | ||
if not left_unique and not right_unique: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use in [..., ...]
8874c7d
to
e5a6ee1
Compare
Codecov Report
@@ Coverage Diff @@
## master #16275 +/- ##
==========================================
- Coverage 90.34% 90.33% -0.02%
==========================================
Files 167 167
Lines 50908 50935 +27
==========================================
+ Hits 45994 46011 +17
- Misses 4914 4924 +10
Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #16275 +/- ##
==========================================
+ Coverage 90.38% 90.41% +0.03%
==========================================
Files 161 161
Lines 50999 51024 +25
==========================================
+ Hits 46096 46134 +38
+ Misses 4903 4890 -13
Continue to review full report at Codecov.
|
@jreback I'm not sure the code in the PR checklist ( |
@jreback thanks -- but on my system I got no errors, when I had trailing white space and excessive empty lines between lines. I think the command should be |
if u read the doc it explains what upstream/master is |
I'm fine with upstream/master (I was copying off doc which just has master). I think the problem is the |
|
I have this an alias and it works like a charm: yeah arg ordering does sometimes matter. |
So maybe we need to change the check box command. Should i open as issue? |
you can just do a PR (also make sure the constributing docs are consistent). |
pandas/core/frame.py
Outdated
@@ -174,6 +174,17 @@ | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
validate: None or string, default None | |||
If specified, checks to ensure merge is of specified type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need -
or *
on these? @jorisvandenbossche ?
pandas/core/frame.py
Outdated
validate: None or string, default None | ||
If specified, checks to ensure merge is of specified type. | ||
If "one_to_one" or "1:1", checks merge keys are unique in both | ||
left and right dataset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checks if merge keys (and same on all)
pandas/core/reshape/merge.py
Outdated
@@ -952,6 +959,51 @@ def _validate_specification(self): | |||
if len(self.right_on) != len(self.left_on): | |||
raise ValueError("len(right_on) must equal len(left_on)") | |||
|
|||
def _validate(self): | |||
# Get merging series: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply use self.left_join_keys
and self.right_join_keys
which are already lists of arrays (1 or more). No need to repeat this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried that, but if I want to use duplicated()
, it ends up taking just as much additional code (or more) to work with self.right_join_keys
or self.left_join_keys
-- I have to coerce them into DataFrames in a way that's amenable to their variable potential dimensions, then run duplicates. I don't think that's actually any better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
show what u r doing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternate? Shortest safe one I have is:
pd.concat(list(map(pd.Series, left_keys)), axis='columns')
pandas/core/reshape/merge.py
Outdated
@@ -561,6 +565,9 @@ def __init__(self, left, right, how='inner', on=None, | |||
# to avoid incompat dtypes | |||
self._maybe_coerce_merge_keys() | |||
|
|||
if self.validate is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a comment here on what is happening, pass in validate
and don't make it an instance variable. This will just raise if there is an error.
@@ -724,6 +724,63 @@ def test_indicator(self): | |||
how='outer', indicator=True) | |||
assert_frame_equal(test5, hand_coded_result) | |||
|
|||
def test_validation(self): | |||
left = DataFrame({'a': ['a', 'b', 'c', 'd'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add tests for merge_asof
this applies to it as well (different file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
doc/source/whatsnew/v0.21.0.txt
Outdated
|
||
The ``validate`` argument for :func:`merge` function now checks whether a merge is | ||
one-to-one, one-to-many, many-to-one, or many-to-many. If a merge is found to not | ||
be an example of specified merge type, an exception will be raised. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue number at the end. You can just add this to Other Enhancements, doesn't need a sub-section (unless you want to add a full-on example).
can you add a small section in merge docs (and link from the doc-string to this). Also an example in the doc-string would be good as well. Finally there is an existing warning in the docs somewhat about this (e.g. checking for duplicates), can you revise. |
doc/source/merging.rst
Outdated
may result in memory overflow. It is the user' s responsibility to manage duplicate values in keys before joining large DataFrames. | ||
Joining / merging on duplicate keys can cause a returned frame that is the multiplication of the row dimensions, which may result in memory overflow. It is the user' s responsibility to manage duplicate values in keys before joining large DataFrames. | ||
|
||
Checking for duplicate keys |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
versionadded tag, add a ref tag as well (e.g. _merging.validation::
)
doc/source/merging.rst
Outdated
|
||
right = pd.DataFrame({'A' : [4,5,6], 'B': [2, 2, 2]}) | ||
|
||
result = pd.merge(left, right, on='B', how='outer', validate="one_to_one"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this raises, so better to use a code-block and show what this is going to raise.
@@ -724,6 +724,63 @@ def test_indicator(self): | |||
how='outer', indicator=True) | |||
assert_frame_equal(test5, hand_coded_result) | |||
|
|||
def test_validation(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than repeating tests I think pull these out to another test file, test_api
and run thru both merge and merge_asof (parametrize is best)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only issue I see is that there are requirements for merge_as
that don't apply to merge
(for example, merge_as
requires sorting). I can do this, but will limit set of tests I can run to those that work on both (current tests for merge
don't work for merge_asof
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just do some simple validation then (and leave them where they are). having completely duplicated tests is not that useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Added some simple validations to merge_asof
pandas/core/reshape/merge.py
Outdated
if self.right_index: | ||
right_unique = not (self.orig_right.index.duplicated()).any() | ||
else: | ||
right_unique = not (self.orig_right[right_key].duplicated()).any() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something like
MultiIndex.from_array(self.left_join_keys).is_unique
is more clear / faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not convinced that's more readable then just having that original pandas code, but will put in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nickeubank the point is you are repeating lots of code for no reason. The notion of figuring out which is what (from the input args) is actually non-trivial and will be refactored shortly. Don't repeat it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #16228 for the issue
doc/source/merging.rst
Outdated
- ``validate`` : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", "many_to_one", "many_to_many"}, default None | ||
If specified, checks if merge is of specified type. | ||
* "one_to_one" or "1:1": check if merge keys are unique in both | ||
left and right dataset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
datasets
doc/source/merging.rst
Outdated
@@ -551,6 +552,18 @@ standard database join operations between DataFrame objects: | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
- ``validate`` : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", "many_to_one", "many_to_many"}, default None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would split this up and put the choices on the 2nd line, otherwise this gets too long (or you can use \
to split the line). maybe check how this all renders.
doc/source/merging.rst
Outdated
In the following example, there are duplicate values of ``B`` in the right DataFrame. As this is not a one-to-one merge -- as specified in the ``validate`` argument -- an exception will be raised. | ||
|
||
.. code-block:: python | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when using code-block, need to copy-past exactly from an ipython section (e.g. formatting counts).
doc/source/merging.rst
Outdated
|
||
If the user is aware of the duplicates in the right `DataFrame` but wants to ensure there are no duplicates in the left DataFrame, one can use the `one_to_many` argument instead, which will not raise an exception. | ||
|
||
.. ipython:: python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to move this block before the other one and actually run it, then the previous code-block only needs to show the merge operation (as you will have already shown the df when you remove the suppress)
pandas/core/frame.py
Outdated
validate : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", | ||
"many_to_one", "many_to_many"}, default None | ||
If specified, checks if merge is of specified type. | ||
* "one_to_one" or "1:1": check if merge keys are unique in both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to indent the 2nd row after the *
@jorisvandenbossche ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also needs a blank line above this one (to delineate the itemize block)
pandas/core/reshape/merge.py
Outdated
@@ -341,6 +344,19 @@ def merge_asof(left, right, on=None, | |||
|
|||
.. versionadded:: 0.20.0 | |||
|
|||
validate : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", | |||
"many_to_one", "many_to_many"}, default None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same. as an aside we ought to use a template for these merge* doc-strings
def _validate(self, validate): | ||
|
||
# Check uniqueness of each | ||
if self.left_index: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not self.orig_left.index.is_unique
left_unique = MultiIndex.from_arrays(self.left_join_keys | ||
).is_unique | ||
|
||
if self.right_index: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
pandas/tests/reshape/test_merge.py
Outdated
'nay', 'chirp']}, | ||
index=range(5)) | ||
|
||
merge(left, right, left_index=True, right_index=True, validate='1:1') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment on why you are not checking the result values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I actually should test those come to think of it -- in theory no impact on output (it's just tests), but no reason to make that a tested behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if I find it making sense to also have this keyword for the merge_asof
, as you do not match on exact keys anyway, but on the nearest.
Further, this also gets complicated because eg the allow_exact_matches
can actually influence the fact there would be duplicate keys or not.
Further, the explanation should also be different, as you don't have the same concept of a "one_to_many" merge as you have with the normal merge, because even if you have duplicate keys, you end up with a one_to_one kind of merge
doc/source/merging.rst
Outdated
@@ -551,6 +552,18 @@ standard database join operations between DataFrame objects: | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
- ``validate`` : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", "many_to_one", "many_to_many"}, default None | |||
If specified, checks if merge is of specified type. | |||
* "one_to_one" or "1:1": check if merge keys are unique in both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a blank line above this one (to delineate the itemize)
doc/source/merging.rst
Outdated
- ``validate`` : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", "many_to_one", "many_to_many"}, default None | ||
If specified, checks if merge is of specified type. | ||
* "one_to_one" or "1:1": check if merge keys are unique in both | ||
left and right dataset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has to be indented at the same level as "one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and the same for the two items below
pandas/core/frame.py
Outdated
validate : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", | ||
"many_to_one", "many_to_many"}, default None | ||
If specified, checks if merge is of specified type. | ||
* "one_to_one" or "1:1": check if merge keys are unique in both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed
pandas/core/frame.py
Outdated
validate : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", | ||
"many_to_one", "many_to_many"}, default None | ||
If specified, checks if merge is of specified type. | ||
* "one_to_one" or "1:1": check if merge keys are unique in both |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also needs a blank line above this one (to delineate the itemize block)
pandas/core/frame.py
Outdated
@@ -174,6 +174,18 @@ | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
validate : {None, '1:1', '1:m', 'm:1', 'm:m', "one_to_one", "one_to_many", | |||
"many_to_one", "many_to_many"}, default None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
many_to_many is listed as a possibility, but is not explained in the list below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formatting here (multiple lines for the type specification, to render nice in the html docs it has to fit on one line) currently does not work nice with numpydoc (see numpy/numpydoc#87)
Putting just string, default None
and then the options are in the list below is an alternative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jorisvandenbossche This relates to the question at the top of this PR: should we check the manys? In other words, if someone passed "one_to_many" but the merge is actually "one_to_one", is that ok?
My sense is that's fine -- i've never been in a situation where getting 1:1 where I expected 1:m was a problem -- but one corollary is that "many_to_many" doesn't actually do anything. I like the idea of leaving it there -- it's nice to be able to label ones merges consistently in this way -- but that specification doesn't imply any tests (which is why I left it off the list).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree with the idea of not checking that a 'many' is in practice a 'one'. So this means that 'many_to_many' should check nothing.
But apart from that, we should either not have it as an option, or either include it in the docstring (and just say that this does do nothing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you already did that in the meantime!
pandas/core/reshape/merge.py
Outdated
).is_unique | ||
|
||
# Check valid arg | ||
if validate not in ['one_to_one', '1:1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can also put this in the end as an else clause, then don't need to list all options here again
pandas/core/reshape/merge.py
Outdated
raise ValueError("Merge keys are not unique in right dataset;" | ||
" not a one-to-one merge") | ||
|
||
if validate in ["one_to_many", "1:m"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if -> elif (the same below) (makes it clearer code-wise they are exclusive if statements)
# Check invalid arguments | ||
with pytest.raises(ValueError): | ||
merge(left, right, on='a', validate='jibberish') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also add tests for when merging on multiple columns (and maybe also one test where combining eg left_index and right_on, but not needed to that for all of them)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with dropping from merge_asof
. @jreback you ok with that?
yep |
9c24834
to
d7de5fa
Compare
doc/source/merging.rst
Outdated
dataset. | ||
* "many_to_one" or "m:1": checks if merge keys are unique in right | ||
dataset. | ||
* "many_to_may" or "m:m": allowed, but does not result in checks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may -> many
doc/source/merging.rst
Outdated
988 elif not right_unique: | ||
--> 989 raise ValueError("Merge keys are not unique in right dataset;" | ||
990 " not a one-to-one merge") | ||
991 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can truncate this to only the final 'ValueError: .... ' line
doc/source/whatsnew/v0.21.0.txt
Outdated
``validate`` argument checks merge key uniqueness | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
The ``validate`` argument for :func:`merge` function now checks whether a merge is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the merge function
and maybe "the optional validate argument" (to make clear that is not the default to check something)
pandas/core/frame.py
Outdated
@@ -174,6 +174,19 @@ | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
validate : String, default None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(minor nitpick) String -> string
8b8f3b0
to
0c2ef6f
Compare
@jorisvandenbossche @jreback Think I covered all suggestions! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some doc/style comments
doc/source/merging.rst
Outdated
@@ -551,6 +552,21 @@ standard database join operations between DataFrame objects: | |||
|
|||
.. versionadded:: 0.17.0 | |||
|
|||
- ``validate`` : String, default None | |||
If specified, checks if merge is of specified type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this render? I think it needs indenting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doc/source/merging.rst
Outdated
left = pd.DataFrame({'A' : [1,2], 'B' : [1, 2]}) | ||
right = pd.DataFrame({'A' : [4,5,6], 'B': [2, 2, 2]}) | ||
|
||
.. code-block:: python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to look like ipython output (the code block)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tweaked. jorvis said to suppress most of the traceback, but added the In [] and Out []. If you need anything else, please specify.
doc/source/merging.rst
Outdated
|
||
ValueError: Merge keys are not unique in right dataset; not a one-to-one merge | ||
|
||
If the user is aware of the duplicates in the right `DataFrame` but wants to ensure there are no duplicates in the left DataFrame, one can use the `one_to_many` argument instead, which will not raise an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use validate='one_to_many'
doc/source/whatsnew/v0.21.0.txt
Outdated
|
||
- The ``validate`` argument for :func:`merge` function now checks whether a merge is | ||
one-to-one, one-to-many, many-to-one, or many-to-many. If a merge is found to not | ||
be an example of specified merge type, an exception will be raised. (:issue:`16270`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a link to the doc-section
# Check data integrity | ||
if validate in ["one_to_one", "1:1"]: | ||
if not left_unique and not right_unique: | ||
raise ValueError("Merge keys are not unique in either left" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we might want to raise a MergeError (inherits from ValueError) instead here (as this is what we do for the other operations). Have a look and see if this is inconsistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converted. I think that's fair.
@nickeubank Thanks! |
@nickeubank I just noticed the MergeError comment, which I think you actually did nod not change? (only in the doc) So maybe we can do a follow-up PR if we want to change this from a ValueError to a MergeError. In any case, if we use this error, we also have to move it to |
I agree. let's change ValueError -> MergeError (and then add MergeError to |
@jreback @jorisvandenbossche ugh, sorry -- I updated it but apparently didn't push the commit. Will open new PR. |
git diff upstream/master --name-only -- '*.py' | flake8 --diff
Open question: does not currently check for whether "many" side of a merge is in fact many. I can't think of a case where I'm doing a one-to-many merge and I'd be worried if it was in fact one-to-one, but open to alternate opinions.